﻿using Sales.Mvc.Models;
using System.Text.Json;

namespace Sales.Mvc.Services
{
    public interface IWeatherService
    {
        //根据经纬度获取天气数据
        Task<WeatherApiResponse> GetWeatherAsync(double latitude, double longitude);
        //获取所有已保存的地点坐标列表
        Task<List<LocationCoordinate>> GetSavedLocationsAsync();
        //保存一个新的地点坐标
        Task<bool> SaveLocationAsync(LocationCoordinate location);
        //删除单个已保存的地点
        Task<bool> DeleteLocationAsync(int id);
    }

    public class WeatherService : IWeatherService
    {
        //，用于发送网络请求
        private readonly HttpClient _httpClient;
        //用于记录错误和信息
        private readonly ILogger<WeatherService> _logger;
        //用于读取配置文件
        private readonly IConfiguration _configuration;
        //API的基础地址
        private readonly string _baseUrl = "https://api.openweathermap.org/data/2.5";
        //API密钥
        private readonly string _apiKey;

        public WeatherService(HttpClient httpClient, ILogger<WeatherService> logger, IConfiguration configuration)
        {
            _httpClient = httpClient;
            _logger = logger;
            _configuration = configuration;
            //从配置文件读取API密钥，若未配置则使用默认值
            _apiKey = _configuration["OpenWeatherMap:ApiKey"] ?? "your_openweathermap_api_key_here";
        }
        //获取天气数据
        public async Task<WeatherApiResponse> GetWeatherAsync(double latitude, double longitude)
        {
            try
            {
                // 获取当前天气
                var currentWeatherUrl = $"{_baseUrl}/weather?lat={latitude}&lon={longitude}&appid={_apiKey}&units=metric&lang=zh_cn";
                var currentResponse = await _httpClient.GetAsync(currentWeatherUrl);

                if (!currentResponse.IsSuccessStatusCode)
                {
                    _logger.LogError("获取当前天气数据失败: {StatusCode}", currentResponse.StatusCode);
                    return new WeatherApiResponse { Success = false, Message = "获取当前天气数据失败" };
                }

                // 获取三天预报
                var forecastUrl = $"{_baseUrl}/forecast?lat={latitude}&lon={longitude}&appid={_apiKey}&units=metric&lang=zh_cn&cnt=24";
                var forecastResponse = await _httpClient.GetAsync(forecastUrl);

                if (!forecastResponse.IsSuccessStatusCode)
                {
                    _logger.LogError("获取天气预报数据失败: {StatusCode}", forecastResponse.StatusCode);
                    return new WeatherApiResponse { Success = false, Message = "获取天气预报数据失败" };
                }

                var currentContent = await currentResponse.Content.ReadAsStringAsync();
                var forecastContent = await forecastResponse.Content.ReadAsStringAsync();

                // 解析OpenWeatherMap API响应
                var weatherData = ParseOpenWeatherMapResponse(currentContent, forecastContent, latitude, longitude);

                return new WeatherApiResponse { Success = true, Data = weatherData };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取天气数据时发生错误");
                return new WeatherApiResponse { Success = false, Message = $"获取天气数据失败: {ex.Message}" };
            }
        }

        public async Task<List<LocationCoordinate>> GetSavedLocationsAsync()
        {
            try
            {
                // 这里可以从数据库或配置文件获取保存的位置
                // 暂时返回示例数据
                return new List<LocationCoordinate>
                {
                    new LocationCoordinate { Id = 1, Latitude = 31.2304, Longitude = 121.4737, Name = "上海", CreatedAt = DateTime.Now.AddDays(-1) },
                    new LocationCoordinate { Id = 2, Latitude = 39.9042, Longitude = 116.4074, Name = "北京", CreatedAt = DateTime.Now.AddDays(-2) },
                    new LocationCoordinate { Id = 3, Latitude = 23.1291, Longitude = 113.2644, Name = "广州", CreatedAt = DateTime.Now.AddDays(-3) }
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取保存位置时发生错误");
                return new List<LocationCoordinate>();
            }
        }

        public async Task<bool> SaveLocationAsync(LocationCoordinate location)
        {
            try
            {
                // 这里可以保存到数据库或配置文件
                // 暂时返回成功
                _logger.LogInformation("保存位置: {Name} ({Latitude}, {Longitude})", location.Name, location.Latitude, location.Longitude);
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存位置时发生错误");
                return false;
            }
        }

        public async Task<bool> DeleteLocationAsync(int id)
        {
            try
            {
                // 这里可以从数据库或配置文件删除位置
                // 暂时返回成功
                _logger.LogInformation("删除位置 ID: {Id}", id);
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除位置时发生错误");
                return false;
            }
        }

        public async Task<bool> DeleteMultipleLocationsAsync(List<int> ids)
        {
            try
            {
                // 这里可以批量删除位置
                // 暂时返回成功
                _logger.LogInformation("批量删除位置 IDs: {Ids}", string.Join(", ", ids));
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量删除位置时发生错误");
                return false;
            }
        }

        private WeatherData ParseOpenWeatherMapResponse(string currentJson, string forecastJson, double latitude, double longitude)
        {
            try
            {
                //析当前天气JSON为可操作的JsonDocument
                using var currentDoc = JsonDocument.Parse(currentJson);
                //解析预报JSON为JsonDocument
                using var forecastDoc = JsonDocument.Parse(forecastJson);
                //获取JSON的根节点（相当于JSON的最外层对象），后续所有属性都从根节点开始读取
                var currentRoot = currentDoc.RootElement;
                var forecastRoot = forecastDoc.RootElement;

                // 解析当前天气
                var current = new CurrentWeather
                {
                    Temperature = currentRoot.GetProperty("main").GetProperty("temp").GetDouble(),//当前温度
                    FeelsLike = currentRoot.GetProperty("main").GetProperty("feels_like").GetDouble(),// 体感温度
                    Humidity = currentRoot.GetProperty("main").GetProperty("humidity").GetInt32(),// 湿度（%）
                    Pressure = currentRoot.GetProperty("main").GetProperty("pressure").GetDouble(),// 气压（hPa）
                    Weather = currentRoot.GetProperty("weather")[0].GetProperty("description").GetString(),// 天气描述
                    WeatherIcon = currentRoot.GetProperty("weather")[0].GetProperty("icon").GetString(),// 天气图标代码
                    WindSpeed = currentRoot.GetProperty("wind").GetProperty("speed").GetDouble(),// 风速（m/s）
                    WindDirection = GetWindDirection(currentRoot.GetProperty("wind").GetProperty("deg").GetDouble()),// 风向
                    Visibility = currentRoot.GetProperty("visibility").GetDouble() / 1000, // 转换为公里  ,能见度
                    AirQuality = 50, // OpenWeatherMap免费版不提供AQI，设置默认值
                    UVIndex = 5 // OpenWeatherMap免费版不提供UV指数，设置默认值
                };

                // 解析三天预报
                var forecasts = new List<WeatherForecast>();
                var forecastList = forecastRoot.GetProperty("list");
                var processedDates = new HashSet<string>();

                foreach (var item in forecastList.EnumerateArray())
                {
                    //解析预报时间：API返回的是Unix时间戳（秒），转换为本地DateTime
                    var dt = DateTimeOffset.FromUnixTimeSeconds(item.GetProperty("dt").GetInt64()).DateTime;
                    var dateKey = dt.ToString("yyyy-MM-dd");

                    // 只处理未来3天的数据，每天取一个代表值（中午12点附近）
                    if (processedDates.Count < 3 && !processedDates.Contains(dateKey) && dt.Hour >= 10 && dt.Hour <= 14)
                    {
                        var main = item.GetProperty("main");
                        var weather = item.GetProperty("weather")[0];
                        var wind = item.GetProperty("wind");

                        var forecast = new WeatherForecast
                        {
                            Date = dt,
                            Temperature = main.GetProperty("temp").GetDouble(),
                            FeelsLike = main.GetProperty("feels_like").GetDouble(),
                            Humidity = main.GetProperty("humidity").GetInt32(),
                            Pressure = main.GetProperty("pressure").GetDouble(),
                            Weather = weather.GetProperty("description").GetString(),
                            WeatherIcon = weather.GetProperty("icon").GetString(),
                            WindSpeed = wind.GetProperty("speed").GetDouble(),
                            WindDirection = GetWindDirection(wind.GetProperty("deg").GetDouble()),
                            AirQuality = 50, // 默认值
                            UVIndex = 5 // 默认值
                        };

                        forecasts.Add(forecast);
                        processedDates.Add(dateKey);
                    }
                }

                // 构建位置信息
                var location = currentRoot.GetProperty("name").GetString();
                if (string.IsNullOrEmpty(location))
                {
                    location = $"纬度: {latitude:F4}, 经度: {longitude:F4}";
                }

                return new WeatherData
                {
                    Location = location,
                    Current = current,
                    Forecasts = forecasts
                };
            }
            catch (Exception ex)
            {
                throw new Exception($"解析天气数据失败: {ex.Message}");
            }
        }

        private string GetWindDirection(double degrees)
        {
            if (degrees >= 337.5 || degrees < 22.5) return "北风";
            if (degrees >= 22.5 && degrees < 67.5) return "东北风";
            if (degrees >= 67.5 && degrees < 112.5) return "东风";
            if (degrees >= 112.5 && degrees < 157.5) return "东南风";
            if (degrees >= 157.5 && degrees < 202.5) return "南风";
            if (degrees >= 202.5 && degrees < 247.5) return "西南风";
            if (degrees >= 247.5 && degrees < 292.5) return "西风";
            if (degrees >= 292.5 && degrees < 337.5) return "西北风";
            return "未知";
        }
    }
}
